/*
* Copyright 2011 Pavel Kozhin 
*
* Licensed under the Apache License, Version 2.0 (the "License"); 
* you may not use this file except in compliance with the License. 
* You may obtain a copy of the License at 
* 
* http://www.apache.org/licenses/LICENSE-2.0
* 
* Unless required by applicable law or agreed to in writing, software 
* distributed  under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
* See the License for the specific language governing permissions and 
* limitations under the License.
*
* Author: Pavel Kozhin.
*/
package org.etherframework.common.utils
{
	import mx.collections.IList;

	// TODO: Refactor
	public final class OU
	{
		public static function getItem(collection:Object, fieldName:String, 
									   fieldValue:*, depth:int = 0, 
									   childrenField:String = "children"):*
		{
			if (!collection)
				return null;
			
			if (collection is IList)
			{
				return parseList(collection as IList, fieldName, 
					fieldValue, depth, childrenField);
			}
			else if ((collection is Array) || (collection is Vector.<*>))
			{
				return parseEnumerable(collection, fieldName, 
					fieldValue, depth, childrenField);
			}
			return null;
		}
		
		public static function areEqual(a:Object, b:Object, fieldName:String = ""):Boolean
		{
			if (fieldName)
			{
				if (!a || !b)
					return false;
				
				if (!(fieldName in a) || !(fieldName in b))
					return false;
				
				return (a[fieldName] == b[fieldName]);
			}
			
			return (a == b);
		}
		
		private static function parseList(collection:IList, fieldName:String, 
										  fieldValue:*, depth:int = 0, 
										  childrenField:String = "children"):Object
		{
			var item:Object;
			var result:Object;
			
			for (var i:int = 0; i < collection.length; i++) 
			{
				item = collection.getItemAt(i);
				
				if (!item.hasOwnProperty(fieldName))
					continue;
				
				if (item[fieldName] == fieldValue)
				{
					result = item;
					break;
				}
				
				if (item.hasOwnProperty(childrenField) && ((depth < 0) || (depth != 0)))
				{
					if (item[childrenField] is IList)
					{
						result = OU.getItem(item[childrenField] as IList, fieldName, 
							fieldValue, --depth, childrenField);
						
						if (result)
							break;
					}
				}
			}
			
			return result;
		}
		
		private static function parseEnumerable(collection:Object, fieldName:String, 
												fieldValue:*, depth:int = 0, 
												childrenField:String = "children"):Object
		{
			var result:Object;
			
			for each (var item:Object in collection) 
			{
				if (!item.hasOwnProperty(fieldName))
					continue;
				
				if (item[fieldName] == fieldValue)
				{
					result = item;
					break;
				}
				
				if (item.hasOwnProperty(childrenField) && ((depth < 0) || (depth != 0)))
				{
					if ((item[childrenField] is Array) || (item[childrenField] is Vector))
					{
						result = OU.getItem(item[childrenField], fieldName, 
							fieldValue, --depth, childrenField);
						
						if (result)
							break;
					}
				}
			}
			return result;
		}
	}
}